home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_098 / thai / translate.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  12KB  |  733 lines

  1. #include "quiz.h"
  2. #include "trans.h"
  3.  
  4.  
  5. static char *z;
  6.  
  7.  
  8. extern char *translate_syllable ();
  9. extern char calc_tone ();
  10.  
  11.  
  12. char *
  13. translate ( input )
  14. char *input;
  15. {
  16.     static char buf[ MAX_STRING ];
  17.     char *oldz;
  18.     char *bp;
  19.     char *extra;
  20.  
  21.     z = input;
  22.     bp = buf;
  23.     *bp = '\0';
  24.     while ( *z != '\0' ) {
  25.         oldz = z;
  26.         extra = translate_syllable ();
  27.         if ( extra != NULL ) {
  28.             strcat ( buf , extra );
  29.             strcat ( buf , " " );
  30.         }
  31.         if ( z == oldz )
  32.             break;    /* algorithm failed - give up */
  33.     }
  34.     return ( buf );
  35. }
  36.  
  37.  
  38. /*
  39.  *  Does not yet handle:
  40.  *
  41.  * TAH! NAI  (TAW_TAH_HAHN NAW_NOO AH YAW_YAHK)
  42.  * also final consonant seems to be optional 
  43.  *
  44.  */
  45.  
  46.  
  47. static char *
  48. translate_syllable ()
  49. {
  50.     static char buf[ 10 ];
  51.  
  52.     char *initial = NULL;
  53.     char *vowel = NULL;
  54.     char *final = NULL;
  55.     char tone = 'c';
  56.     char initial_char = '\0';
  57.     char final_char = '\0';
  58.     char tone_mark = '\0';
  59.  
  60.     if ( *z == TC_EH ) {
  61.         z++;
  62.         if ( *z == TC_EH ) {
  63.             z++;
  64.             initial_consonant ( &initial , &initial_char , &tone_mark );
  65.             if ( *z == TC_SHORT_AH ) {
  66.                 vowel = "AA!";
  67.                 z++;
  68.             }
  69.             else {
  70.                 vowel = "AA";
  71.                 final_consonant ( &final , &final_char );
  72.             }
  73.         }
  74.         else {
  75.             initial_consonant ( &initial , &initial_char , &tone_mark );
  76.             switch ( *z ) {
  77.  
  78.             case TC_AW :
  79.                 z++;
  80.                 if ( *z == TC_SHORT_AH ) {
  81.                     z++;
  82.                     vowel = "UH!";
  83.                 }
  84.                 else
  85.                     vowel = "UH";
  86.                 break;
  87.  
  88.             case TC_SHORT_AH :
  89.                 z++;
  90.                 vowel = "EH!";
  91.                 break;
  92.  
  93.             case TC_LONG_AH :
  94.                 z++;
  95.                 if ( *z == TC_SHORT_AH ) {
  96.                     z++;
  97.                     vowel = "AW!";
  98.                 }
  99.                 else {
  100.                     vowel = "AO!";
  101.                     final_consonant ( &final , &final_char );
  102.                 }
  103.                 break;
  104.  
  105.             case TC_IH :
  106.                 z++;
  107.                 vowel = "UH";
  108.                 final_consonant ( &final , &final_char );
  109.                 break;
  110.  
  111.             case TC_EE :
  112.                 if ( *(z+1) == TC_YAW_YAHK ) {
  113.                     z += 2;
  114.                     if ( *z == TC_SHORT_AH ) {
  115.                         z++;
  116.                         vowel = "IA!";
  117.                     }
  118.                     else {
  119.                         vowel = "IA";
  120.                         final_consonant ( &final , &final_char );
  121.                     }
  122.                 }
  123.                 else
  124.                     vowel = NULL;    /* error really */
  125.                 break;
  126.  
  127.             case TC_LONG_EU :
  128.                 if ( *(z+1) == TC_AW ) {
  129.                     z += 2;
  130.                     if ( *z == TC_SHORT_AH ) {
  131.                         z++;
  132.                         vowel = "EUA!";
  133.                     }
  134.                     else {
  135.                         vowel = "EUA";
  136.                         final_consonant ( &final , &final_char );
  137.                     }
  138.                 }
  139.                 else
  140.                     vowel = NULL;    /* error really */
  141.                 break;
  142.  
  143.             default :
  144.                 vowel = "EH";
  145.                 final_consonant ( &final , &final_char );
  146.                 break;
  147.             }
  148.         }
  149.     }
  150.     else if ( *z == TC_OH ) {
  151.         z++;
  152.         initial_consonant ( &initial , &initial_char , &tone_mark );
  153.         if ( *z == TC_SHORT_AH ) {
  154.             z++;
  155.             vowel = "OH!";
  156.         }
  157.         else {
  158.             vowel = "OH";
  159.             final_consonant ( &final , &final_char );
  160.         }
  161.     }
  162.     else if ( *z == TC_AI20  ||  *z == TC_AI ) {
  163.         z++;
  164.         initial_consonant ( &initial , &initial_char , &tone_mark );
  165.         vowel = "AI!";
  166.         final_consonant ( &final , &final_char );
  167.     }
  168.     else {
  169.         initial_consonant ( &initial , &initial_char , &tone_mark );
  170.         if ( *z == TC_WAW  &&  isconsonant( *(z+1) ) ) {
  171.             z++;
  172.             vowel = "UA";
  173.             final_consonant ( &final , &final_char );
  174.         }
  175.         else if ( *z == TC_RAW_REUA  &&  *(z+1) == TC_RAW_REUA ) {
  176.             vowel = "AH!";
  177.             final_consonant ( &final , &final_char );
  178.         }
  179.         else {
  180.             switch ( *z ) {
  181.  
  182.             case TC_SHORT_AH :
  183.                 z++;
  184.                 vowel = "AH!";
  185.                 break;
  186.  
  187.             case TC_SHORT_AH_ABOVE :
  188.                 z++;
  189.                 if ( *z == TC_WAW ) {
  190.                     z++;
  191.                     vowel = "UA!";
  192.                 }
  193.                 else {
  194.                     vowel = "AH!";
  195.                     final_consonant ( &final , &final_char );
  196.                 }
  197.                 break;
  198.  
  199.             case TC_LONG_AH :
  200.                 z++;
  201.                 if ( *z == TC_WAW ) {
  202.                     z++;
  203.                     vowel = "AO";
  204.                 }
  205.                 else if ( *z == TC_YAW_YAHK ) {
  206.                     z++;
  207.                     vowel = "AI";
  208.                 }
  209.                 else {
  210.                     vowel = "AH";
  211.                     final_consonant ( &final , &final_char );
  212.                 }
  213.                 break;
  214.  
  215.             case TC_AHM :
  216.                 z++;
  217.                 vowel = "AH!M";
  218.                 break;
  219.  
  220.             case TC_IH :
  221.                 z++;
  222.                 vowel = "IH!";
  223.                 final_consonant ( &final , &final_char );
  224.                 break;
  225.  
  226.             case TC_EE :
  227.                 z++;
  228.                 vowel = "EE";
  229.                 final_consonant ( &final , &final_char );
  230.                 break;
  231.  
  232.             case TC_SHORT_EU :
  233.                 z++;
  234.                 vowel = "EU!";
  235.                 final_consonant ( &final , &final_char );
  236.                 break;
  237.  
  238.             case TC_LONG_EU :
  239.                 z++;
  240.                 vowel = "EU";
  241.                 final_consonant ( &final , &final_char );
  242.                 break;
  243.  
  244.             case TC_SHORT_OO :
  245.                 z++;
  246.                 vowel = "OO!";
  247.                 final_consonant ( &final , &final_char );
  248.                 break;
  249.  
  250.             case TC_LONG_OO :
  251.                 z++;
  252.                 vowel = "OO";
  253.                 final_consonant ( &final , &final_char );
  254.                 break;
  255.  
  256.             case TC_AW :
  257.                 z++;
  258.                 vowel = "AW";
  259.                 final_consonant ( &final , &final_char );
  260.                 break;
  261.  
  262.             default :
  263.                 if ( isconsonant(*z)  &&  ! isaftervowel( *(z+1) ) ) {
  264.                     vowel = "OH!";
  265.                     final_consonant ( &final , &final_char );
  266.                 }
  267.                 else {
  268.                     vowel = "AH!";
  269.                 }
  270.                 break;
  271.             }
  272.         }
  273.     }
  274.     tone = calc_tone ( initial , initial_char , tone_mark , vowel ,
  275.         final , final_char );
  276.  
  277.     strcpy ( buf , "(x)" );
  278.     buf[1] = tone;
  279.  
  280.     if ( initial != NULL )
  281.         strcat ( buf , initial );
  282.     if ( vowel != NULL )
  283.         strcat ( buf , vowel );
  284.     if ( final != NULL )
  285.         strcat ( buf , final );
  286.     return ( buf );
  287. }
  288.  
  289.  
  290. static
  291. initial_consonant ( phoneme , c , tone_mark )
  292. char **phoneme;
  293. char *c;
  294. char *tone_mark;
  295. {
  296.     char dummy;
  297.  
  298.     *phoneme = NULL;
  299.     *c = *z;
  300.  
  301.     switch ( *z++ ) {
  302.  
  303.     case TC_GAW :
  304.         if ( *z == TC_LAW_LEENG ) {
  305.             z++;
  306.             *phoneme = "GL";
  307.         }
  308.         else if ( *z == TC_RAW_REUA ) {
  309.             z++;
  310.             *phoneme = "GR";
  311.         }
  312.         else
  313.             *phoneme = "G";
  314.         break;
  315.  
  316.     case TC_KAW_KAI :
  317.     case TC_KAW_KUAT :
  318.     case TC_KAW_KWAI :
  319.     case TC_KAW_KOHN :
  320.     case TC_KAW_RAH_KAHNG :
  321.         if ( *z == TC_LAW_LEENG ) {
  322.             z++;
  323.             *phoneme = "KL";
  324.         }
  325.         else if ( *z == TC_RAW_REUA ) {
  326.             z++;
  327.             *phoneme = "KR";
  328.         }
  329.         else
  330.             *phoneme = "K";
  331.         break;
  332.  
  333.     case TC_NGAW :
  334.         *phoneme = "NG";
  335.         break;
  336.  
  337.     case TC_JAW :
  338.         *phoneme = "J";
  339.         break;
  340.  
  341.     case TC_CHAW :
  342.     case TC_CHAW_CHANG :
  343.     case TC_CHAW_CHUH :
  344.         *phoneme = "CH";
  345.         break;
  346.  
  347.     case TC_SAW :
  348.     case TC_SAW_SAH_LAH :
  349.     case TC_SAW_REU_SEE :
  350.     case TC_SAW_SEUA :
  351.         *phoneme = "S";
  352.         break;
  353.  
  354.     case TC_YAW_YEENG :
  355.     case TC_YAW_YAHK :
  356.         *phoneme = "Y";
  357.         break;
  358.  
  359.     case TC_DAW_CHAH_DAH :
  360.     case TC_DAW_DEHK :
  361.         *phoneme = "D";
  362.         break;
  363.  
  364.     case TC_DTAW_BPAH_DTAHK :
  365.     case TC_DTAW_DTAO :
  366.         *phoneme = "DT";
  367.         break;
  368.  
  369.     case TC_TAW_TAHN :
  370.     case TC_TAW_MOHN_TOH :
  371.     case TC_TAW_POO_TAO :
  372.     case TC_TAW_TOONG :
  373.     case TC_TAW_TAH_HAHN :
  374.     case TC_TAW_TOHNG :
  375.         *phoneme = "T";
  376.         break;
  377.  
  378.     case TC_NAW_NEHN :
  379.     case TC_NAW_NOO :
  380.         *phoneme = "N";
  381.         break;
  382.  
  383.     case TC_BAW :
  384.         *phoneme = "B";
  385.         break;
  386.  
  387.     case TC_BPAW :
  388.         *phoneme = "BP";
  389.         break;
  390.  
  391.     case TC_PAW :
  392.     case TC_PAW_PAHN :
  393.     case TC_PAW_SAHM_PAO :
  394.         *phoneme = "P";
  395.         break;
  396.  
  397.     case TC_FAW_HIGH :
  398.     case TC_FAW :
  399.         *phoneme = "F";
  400.         break;
  401.  
  402.     case TC_MAW :
  403.         *phoneme = "M";
  404.         break;
  405.  
  406.     case TC_RAW_REUA :
  407.         *phoneme = "R";
  408.         break;
  409.  
  410.     case TC_LAW_LEENG :
  411.     case TC_LAW_JOOH_LAH :
  412.         *phoneme = "L";
  413.         break;
  414.  
  415.     case TC_WAW :
  416.         *phoneme = "W";
  417.         break;
  418.  
  419.     case TC_AW :
  420.         *phoneme = "AW";
  421.         break;
  422.  
  423.     case TC_HAW :
  424.         if ( isconsonant ( *z )  &&  ! isaftervowel ( *(z+1) ) )
  425.             initial_consonant ( phoneme , &dummy , tone_mark );
  426.         else
  427.             *phoneme = "H";
  428.         break;
  429.  
  430.     case TC_HAH :
  431.         *phoneme = "H";
  432.         break;
  433.     }
  434.  
  435.     switch ( *z ) {
  436.  
  437.     case TC_MAI_EHK :
  438.     case TC_MAI_TOH :
  439.     case TC_MAI_DTREE :
  440.     case TC_MAI_JATTAWA :
  441.         *tone_mark = *z++;
  442.         break;
  443.  
  444.     default :
  445.         *tone_mark = '\0';
  446.     }
  447. }
  448.  
  449.  
  450. static
  451. final_consonant ( phoneme , c , tone_mark )
  452. char **phoneme;
  453. char *c;
  454. char *tone_mark;
  455. {
  456.     /* check if user put tone mark in wrong spot */
  457.  
  458.     switch ( *z ) {
  459.  
  460.     case TC_MAI_EHK :
  461.     case TC_MAI_TOH :
  462.     case TC_MAI_DTREE :
  463.     case TC_MAI_JATTAWA :
  464.         *tone_mark = *z++;
  465.         break;
  466.  
  467.     default :
  468.         break;    /* dont overide the old value then */
  469.     }
  470.  
  471.     *c = *z;
  472.  
  473.     if ( isconsonant( z[0] )  &&  ! isaftervowel( z[1] ) ) {
  474.         switch ( *z++ ) {
  475.  
  476.         case TC_GAW :
  477.         case TC_KAW_KAI :
  478.         case TC_KAW_KUAT :
  479.         case TC_KAW_KWAI :
  480.         case TC_KAW_KOHN :
  481.         case TC_KAW_RAH_KAHNG :
  482.             *phoneme = "K";
  483.             break;
  484.  
  485.         case TC_NGAW :
  486.             *phoneme = "NG";
  487.             break;
  488.  
  489.         case TC_JAW :
  490.         case TC_CHAW :
  491.         case TC_CHAW_CHANG :
  492.         case TC_SAW :
  493.         case TC_CHAW_CHUH :
  494.         case TC_DAW_CHAH_DAH :
  495.         case TC_DTAW_BPAH_DTAHK :
  496.         case TC_TAW_TAHN :
  497.         case TC_TAW_MOHN_TOH :
  498.         case TC_TAW_POO_TAO :
  499.         case TC_DAW_DEHK :
  500.         case TC_DTAW_DTAO :
  501.         case TC_TAW_TOONG :
  502.         case TC_TAW_TAH_HAHN :
  503.         case TC_TAW_TOHNG :
  504.         case TC_SAW_SAH_LAH :
  505.         case TC_SAW_REU_SEE :
  506.         case TC_SAW_SEUA :
  507.             *phoneme = "T";
  508.             break;
  509.  
  510.         case TC_NAW_NEHN :
  511.         case TC_YAW_YEENG :
  512.         case TC_NAW_NOO :
  513.         case TC_RAW_REUA :
  514.         case TC_LAW_LEENG :
  515.         case TC_LAW_JOOH_LAH :
  516.             *phoneme = "N";
  517.             break;
  518.  
  519.         case TC_BAW :
  520.         case TC_BPAW :
  521.         case TC_PAW :
  522.         case TC_PAW_PAHN :
  523.         case TC_PAW_SAHM_PAO :
  524.             *phoneme = "P";
  525.             break;
  526.  
  527.         case TC_FAW :
  528.             *phoneme = "F";
  529.             break;
  530.  
  531.         case TC_MAW :
  532.             *phoneme = "M";
  533.             break;
  534.  
  535.         case TC_YAW_YAHK :
  536.         case TC_WAW :
  537.             *phoneme = NULL;
  538.             break;
  539.  
  540.         case TC_FAW_HIGH :
  541.         case TC_HAW :
  542.         case TC_HAH :
  543.         case TC_AW :
  544.             *phoneme = "";        /* silent */
  545.             break;
  546.  
  547.         default :
  548.             *phoneme = NULL;
  549.             break;
  550.         }
  551.     }
  552.     else
  553.         *phoneme = NULL;
  554. }
  555.  
  556.  
  557. static char
  558. calc_tone ( initial , initial_char , tone_mark , vowel , final , final_char )
  559. char *initial;
  560. char initial_char;
  561. char tone_mark;
  562. char *vowel;
  563. char *final;
  564. char final_char;
  565. {
  566.     char tone;
  567.     int long_vowel;
  568.  
  569.     tone = 'c';
  570.     if ( initial == NULL  ||  initial[0] == '\0' )
  571.         return ( tone );
  572.     if ( vowel == NULL  ||  vowel[0] == '\0' )
  573.         return ( tone );
  574.  
  575.     long_vowel = ( vowel[ strlen ( vowel ) - 1 ] != '!' );
  576.  
  577.     if ( tone_mark == TC_MAI_DTREE )
  578.         tone = 'r';
  579.     else if ( ishigh( initial_char ) ) {
  580.         if ( tone_mark == TC_MAI_TOH ) {
  581.             tone = 'f';
  582.         }
  583.         else if ( final == NULL  ||  final[0] == '\0' ) {
  584.             if ( long_vowel ) {
  585.                 if ( tone_mark == '\0' ) {
  586.                     tone = 'r';
  587.                 }
  588.                 else if ( tone_mark == TC_MAI_EHK ) {
  589.                     tone = 'l';
  590.                 }
  591.             }
  592.             else {
  593.                 if ( tone_mark == '\0' ) {
  594.                     tone = 'l';
  595.                 }
  596.             }
  597.         }
  598.         else {
  599.             switch ( final[0] ) {
  600.  
  601.             case 'A' :
  602.                 if ( final[1] != 'I'  ||  final[1] == 'O' )
  603.                     tone = 'r';
  604.                 break;
  605.  
  606.             case 'M' :
  607.             case 'N' :
  608.             case 'W' :
  609.             case 'Y' :
  610.                 tone = 'r';
  611.                 break;
  612.  
  613.             case 'K' :
  614.             case 'P' :
  615.             case 'T' :
  616.                 tone = 'l';
  617.                 break;
  618.             }
  619.         }
  620.     }
  621.     else if ( ismiddle( initial_char ) ) {
  622.         if ( tone_mark == TC_MAI_EHK ) {
  623.             tone = 'l';
  624.         }
  625.         else if ( tone_mark == TC_MAI_TOH ) {
  626.             tone = 'f';
  627.         }
  628.         else {
  629.             if ( final == NULL  ||  final[0] == '\0' ) {
  630.                 if ( long_vowel ) {
  631.                     if ( tone_mark == '\0' ) {
  632.                         tone = 'c';
  633.                     }
  634.                     else {
  635.                     }
  636.                 }
  637.                 else {
  638.                     if ( tone_mark == '\0' ) {
  639.                         tone = 'l';
  640.                     }
  641.                     else {
  642.                     }
  643.                 }
  644.             }
  645.             else {
  646.                 switch ( final[0] ) {
  647.  
  648.                 case 'A' :
  649.                     if ( final[1] == 'O'  ||  final[1] == 'I' ) {
  650.                         if ( islow( final_char ) ) {
  651.                             tone = 'c';
  652.                         }
  653.                     }
  654.                     break;
  655.  
  656.                 case 'M' :
  657.                 case 'N' :
  658.                 case 'W' :
  659.                 case 'Y' :
  660.                     if ( islow( final_char ) ) {
  661.                         tone = 'c';
  662.                     }
  663.                     break;
  664.  
  665.                 case 'K' :
  666.                 case 'P' :
  667.                 case 'T' :
  668.                     tone = 'l';
  669.                     break;
  670.                 }
  671.             }
  672.         }
  673.     }
  674.     else if ( islow( initial_char ) ) {
  675.         if ( tone_mark == TC_MAI_EHK ) {
  676.             tone = 'f';
  677.         }
  678.         else if ( tone_mark == TC_MAI_TOH ) {
  679.             tone = 'h';
  680.         }
  681.         else if ( tone_mark == '\0' ) {
  682.             if ( long_vowel ) {
  683.                 if ( final == NULL  ||  final[0] == '\0' ) {
  684.                     tone = 'c';
  685.                 }
  686.                 else {
  687.                     switch ( final[0] ) {
  688.  
  689.                     case 'K' :
  690.                     case 'P' :
  691.                     case 'T' :
  692.                         tone = 'f';
  693.                         break;
  694.                     }
  695.                 }
  696.             }
  697.             else {
  698.                 if ( final == NULL  ||  final[0] == '\0' ) {
  699.                     tone = 'h';
  700.                 }
  701.                 else {
  702.                     switch ( final[0] ) {
  703.  
  704.                     case 'K' :
  705.                     case 'P' :
  706.                     case 'T' :
  707.                         tone = 'h';
  708.                         break;
  709.  
  710.                     case 'A' :
  711.                         if ( final[1] == 'O'  ||  final[1] == 'I' ) {
  712.                             if ( islow( final_char ) ) {
  713.                                 tone = 'c';
  714.                             }
  715.                         }
  716.                         break;
  717.  
  718.                     case 'M' :
  719.                     case 'N' :
  720.                     case 'W' :
  721.                     case 'Y' :
  722.                         if ( islow( final_char ) ) {
  723.                             tone = 'c';
  724.                         }
  725.                         break;
  726.                     }
  727.                 }
  728.             }
  729.         }
  730.     }
  731.     return ( tone );
  732. }
  733.